﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace ManPowerEngine
{
	/// <summary>
	/// A simplest box collider
	/// </summary>
	public class BoxCollider : ColliderBase
	{
		/// <summary>
		/// The width of this collider, if it is not using Renderer's shape info
		/// </summary>
		public int Width;
		/// <summary>
		/// The height of this collider, if it is not using Renderer's shape info
		/// </summary>
		public int Height;
		/// <summary>
		/// The pivot of this collider, if it is not using Renderer's shape info
		/// </summary>
		public Vector Pivot;
		/// <summary>
		/// Whether use renderer's shape info or not
		/// </summary>
		public bool UseRenderer = false;

		/// <summary>
		/// 4 vertices of this box
		/// </summary>
		internal Vector[] iPoints = new Vector[4];
		/// <summary>
		/// leftmost, rightmost, topmost, bottommost in local coordination
		/// </summary>
		private int[] mBounds = new int[4];

		/// <summary>
		/// Create the box collider with using Renderer's shape information.
		/// </summary>
		public BoxCollider()
		{
			UseRenderer = true;
		}

		/// <summary>
		/// Create the box collider with the shape information provided.
		/// </summary>
		/// <param name="width">Width of this box</param>
		/// <param name="height">Height of this box</param>
		/// <param name="pivot">Pivot of this box</param>
		public BoxCollider(int width, int height, Vector pivot)
		{
			UseRenderer = false;
			Width = width;
			Height = height;
			Pivot = pivot;
		}

		/// <summary>
		/// Generates all four points of this rectangle in world coordination
		/// </summary>
		internal void GeneratePoints()
		{
			if (UseRenderer)
			{
				// using geometry data from Renderer
				RendererBase renderer = mGameObject.Renderer;
				Vector[] localpoints = new Vector[] {
					new Vector(0, 0),
					new Vector(renderer.Width, 0),
					new Vector(renderer.Width, renderer.Height),
					new Vector(0, renderer.Height)
				};
				for (int i = 0; i < localpoints.Length; i++)
				{
					iPoints[i] = mGameObject.Transform.LocalToAbsolutePosition(localpoints[i] - renderer.Pivot);
				}				
			}
			else
			{
				// usingt its own geometry data
				Vector[] localpoints = new Vector[] {
					new Vector(0, 0),
					new Vector(Width, 0),
					new Vector(Width, Height),
					new Vector(0, Height)
				};
				for (int i = 0; i < localpoints.Length; i++)
				{
					iPoints[i] = mGameObject.Transform.LocalToAbsolutePosition(localpoints[i] - Pivot);
				}
			}
		}

		/// <summary>
		/// Generate the bounds of this collider
		/// </summary>
		internal void GenerateBounds()
		{
			if (UseRenderer)
			{
				RendererBase renderer = mGameObject.Renderer;
				// left
				mBounds[0] = (int)(-renderer.Pivot.X);
				// right
				mBounds[1] = (int)(renderer.Width - renderer.Pivot.X);
				// top
				mBounds[2] = (int)(-renderer.Pivot.Y);
				// bottom
				mBounds[3] = (int)(renderer.Height - renderer.Pivot.Y);
			}
			else
			{
				// left
				mBounds[0] = (int)(-Pivot.X);
				// right
				mBounds[1] = (int)(Width - Pivot.X);
				// top
				mBounds[2] = (int)(-Pivot.Y);
				// bottom
				mBounds[3] = (int)(Height - Pivot.Y);
			}
		}

		/// <summary>
		/// Check if the a point is in this collider or not.
		/// </summary>
		/// <param name="point">The point that is going to check in world coordination</param>
		/// <returns>if that collider falls into current collider.</returns>
		internal bool PointCheck(Vector point)
		{
			Vector localpos = mGameObject.Transform.AbsoluteToLocalPosition(point);
			bool isIn = (localpos.X >= mBounds[0] && localpos.X <= mBounds[1] && 
				localpos.Y >= mBounds[2] && localpos.Y <= mBounds[3]);
			return isIn;
		}

		internal override bool _OnScreenCheck()
		{
			if (UseRenderer)
			{
				RendererBase renderer = mGameObject.Renderer;
				return RenderSystem.OnScreenCheck(mGameObject.Transform.Position - renderer.Pivot - RenderSystem.CameraPosition, renderer.Width, renderer.Height);
			}
			else
			{
				return RenderSystem.OnScreenCheck(mGameObject.Transform.Position - Pivot - RenderSystem.CameraPosition, Width, Height);
			}
		}
	}
}
